package com.sziit.se.highconcurrency.common.tool;


import com.sziit.se.highconcurrency.common.exception.CustomException;

import java.text.SimpleDateFormat;
import java.time.Clock;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

public class DateTimeUtils {
    private static final String DEFAULT_DATETIME_FORMATS = "yyyy-MM-dd HH:mm:ss";
    private static final String DEFAULT_DATE_FORMATS = "yyyy-MM-dd";
    private static final String SIMPLE_DATE_FORMATS = "yyyyMMdd";
    private static final String DEFAULT_TIME_FORMATS = "HH:mm:ss";

    /**
     * Millis time long.
     *
     * @return the long
     */
    public static long millisTime() {
        return Clock.systemDefaultZone().millis();
    }

    /**
     * Second time long.
     *
     * @return the long
     */
    public static long secondTime() {
        return Clock.systemDefaultZone().millis() / 1000;
    }


    /**
     * Default date time string.
     *
     * @return the string
     */
    public static String nowDateTime() {
        return formatDateTime(LocalDateTime.now());
    }

    public static boolean isToday(String datetime) {
        int tempInt = LocalDate.now().compareTo(parseDateTime(datetime).toLocalDate());
        //如果是今天
        return tempInt == 0;
    }


    /**
     * Default date string.
     *
     * @return the string
     */
    public static String nowDate() {
        return formatDate(LocalDate.now());
    }

    public static String nowDateSimple() {
        return formatDateSimple(LocalDate.now());
    }

    /**
     * Format date time string.
     *
     * @param localDateTime the local date time
     * @param format        the format
     * @return the string
     */
    public static String formatDateTime(LocalDateTime localDateTime, String format) {
        return localDateTime.format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * Format date time to yyyy-MM-dd HH:mm:ss.
     *
     * @param localDateTime the local date time
     * @return the string
     */
    public static String formatDateTime(LocalDateTime localDateTime) {
        return formatDateTime(localDateTime, DEFAULT_DATETIME_FORMATS);
    }

    public static String formatTime(LocalTime localTime) {
        return formatTime(localTime,DEFAULT_TIME_FORMATS);
    }

    public static String formatTime(LocalTime localTime,String format) {
        return localTime.format(DateTimeFormatter.ofPattern(format));
    }



    public static String formatSecondDateTime(Long secondTime) {
        Long time = Long.valueOf(String.format("%-13s", secondTime).replace(' ', '0'));
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATETIME_FORMATS);
        return sdf.format(new Date(time));
    }

    /**
     * Parse date time local date time.
     *
     * @param datetime the datetime
     * @param format   the format
     * @return the local date time
     */
    public static LocalDateTime parseDateTime(String datetime, String format) {
        return LocalDateTime.parse(datetime, DateTimeFormatter.ofPattern(format));
    }

    /**
     * parse date time yyyy-MM-dd HH:mm:ss.
     *
     * @param datetime the datetime
     * @return the local date time
     */
    public static LocalDateTime parseDateTime(String datetime) {
        return parseDateTime(datetime, DEFAULT_DATETIME_FORMATS);
    }

    public static String lastMonthDate() {
        Calendar cal = Calendar.getInstance();
//      设置天数为-1天，表示当月减一天即为上一个月的月末时间
        cal.add(Calendar.MONTH, -1);
        //格式化输出年月日
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_FORMATS);
        return sdf.format(cal.getTime());
    }


    /**
     * Format date string.
     *
     * @param localDate the local date
     * @param format    the format
     * @return the string
     */
    public static String formatDate(LocalDate localDate, String format) {
        return localDate.format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * Format date time to yyyy-MM-dd.
     *
     * @param localDate the local date
     * @return the string
     */
    public static String formatDate(LocalDate localDate) {
        return formatDate(localDate, DEFAULT_DATE_FORMATS);
    }

    public static String formatDateSimple(LocalDate localDate) {
        return formatDate(localDate, SIMPLE_DATE_FORMATS);
    }

    /**
     * Parse date local date time.
     *
     * @param date   the date
     * @param format the format
     * @return the local date time
     */
    public static LocalDate parseDate(String date, String format) {
        return LocalDate.parse(date, DateTimeFormatter.ofPattern(format));
    }

    /**
     * parse date time yyyy-MM-dd.
     *
     * @param date the datetime
     * @return the local date time
     */
    public static LocalDate parseDate(String date) {
        return parseDate(date, DEFAULT_DATE_FORMATS);
    }

    public static LocalTime parseTime(String time, String format) {
        return LocalTime.parse(time, DateTimeFormatter.ofPattern(format));
    }

    public static LocalTime parseTime(String date) {
        return parseTime(date, DEFAULT_TIME_FORMATS);
    }

    public static void checkDateTime(String datetime, String format) {
        try {
            parseDateTime(datetime, format);
        } catch (Exception e) {
            throw new CustomException("日期格式必须是" + format);
        }
    }

    public static void checkDateTime(String datetime) {
        checkDateTime(datetime, DEFAULT_DATETIME_FORMATS);
    }


    public static void checkDate(String date, String format) {
        try {
            parseDate(date, format);
        } catch (Exception e) {
            throw new CustomException("日期格式必须是" + format);
        }
    }

    public static void checkDate(String date) {
        checkDate(date, DEFAULT_DATE_FORMATS);
    }

    public static String datePlusOne(String date){
        LocalDate localDate;
        try {
            localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
        return localDate.plusDays(1).toString();
    }

    public static LocalDate byWeek(int dictionaryWeek) {
        int day = 0;
        int value = LocalDate.now().getDayOfWeek().getValue();
        if (dictionaryWeek == value) {
            day = 7;
        }
        if (value < dictionaryWeek) {
            day = dictionaryWeek - value;
        }
        if (value > dictionaryWeek) {
            day = 7 - (value - dictionaryWeek);
        }
        return LocalDate.now().plusDays(day);
    }

}
